package com.perf

import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.util.Log
import java.lang.StringBuilder

/**
 * @describe:
 * @Author: lixiaopeng
 * @Date: 4/12/21
 */
class Perf :ContentProvider(){

    companion object{
        private const val TAG = "Perf"
    }


    private val minTime = 3000 //如果处理时间大于此值，认为存在arn风险
    private val stringBuilder: StringBuilder by lazy { StringBuilder() }
    private lateinit var handler: Handler

    private var beforeMethodInvoke = true //方法执行前
    private var printerStartTime = 0L

    override fun onCreate(): Boolean {
        val handlerThread = HandlerThread("DelayThread")
        handlerThread.start()
        handler = Handler(handlerThread.looper)
        initPrinter()
        return true
    }

    private fun initPrinter() {
        Looper.getMainLooper().setMessageLogging {
            if (beforeMethodInvoke) {
                beforeMethodInvoke = false
                //记录开始执行的时间
                printerStartTime = System.currentTimeMillis()
                handler.removeCallbacks(runnable)
                //延迟minTime * 0.8发送，用于记录阻塞时的栈信息
                handler.postDelayed(runnable, (minTime * 0.8).toLong())
            } else {
                beforeMethodInvoke = true
                handler.removeCallbacks(runnable)
                (System.currentTimeMillis() - printerStartTime).let {
                    if (it>=minTime){
                        Log.i(TAG, "方法运行的总时长：${it}")
                        Log.i(TAG, "StackTrace：${stringBuilder.toString()}")
                    }
                }
            }
        }
    }

    private val runnable = Runnable {
        stringBuilder.clear()
        for (stack in Looper.getMainLooper().thread.stackTrace) {
            stringBuilder.append(stack.toString())
                    .append("\n")
        }
    }

    override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {
        return null
    }

    override fun getType(uri: Uri): String? {
        return null
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        return null
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
        return 0
    }

    override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?): Int {
        return 0
    }
}